/* 
 * File:   Game.h
 * Author: Pavel Homolka
 *
 * Created on 2. říjen 2011, 17:44
 */

#ifndef GAME_H
#define	GAME_H
#include "Tower.h"
#include "structs.h"

class Game {
public:
    Game();

    Game(const Game& orig);

    ~Game();

    /**
     * @param numberOfDisks numberOfDisks >= 16
     * @param numberOfTowers numberOfDisks/4 >= numberOfTowers > 3
     * @param targetTower
     */
    Game(int numberOfDisks, int numberOfTowers, int targetTower);

    /**
     * Generovani pocatecniho stavu. Nahodne rozmisti disky na veze.
     */
    void newGame();
    void newGame(int*);

    /**
     * Tisk aktualniho stavu hry.
     */
    void printGame();
    void printGame(ostream&);

  
    /**
     * Z pole rozmisteni disku, vytvori vector(pole) vezi
     */
    bool create(int[],vector<Tower*>*);
    
    //Provede zadany tah
    void doMove(Move*);
    
    //Vrati zpet zadany tah
    void undoMove(Move*);
    
    //Vrati vsechny mozne tahy
    vector<Move> getMoves(int);
    
    //Uz sem vyhral?
    bool finished();
    bool backwardMove(Move*,Move*);
    void checkIntegrity();
    vector<Move> play(ofstream&,int&);
    void printMove(Move*);
    void printMove(ofstream&,Move*);
    int* getDiscs();
    friend ostream &operator<<(ostream &stream,Game g);
    void reset();
    long getDone();

private:
    int numberOfDisks;
    int numberOfTowers;
    int targetTower;
//    Tower *towers;
    vector<Tower*> towers;
    int *discs;
    long done;
    vector<Move> actualMoves;
    vector<Move> moves;
    void removeUnusefulMoves(Move*,vector<Move>*);
    int getUpperBound();
    int getLowerBound();
    
    
};

#endif
